﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using FStore.Utils;

namespace FStore.Crypto
{
	/// <summary>
	/// Provides a means of computing an MD5 hash of data
	/// </summary>
	public sealed class MD5HashProvider : IHashProvider
	{
		private MD5 m_provider = null;

		public MD5HashProvider()
		{
			m_provider = MD5.Create();
		}

		/// <summary>
		/// Computes an MD5 hash of a string
		/// </summary>
		/// <param name="data">The string to compute the hash of</param>
		/// <param name="asHex">Whether to express the hash as a Hex string</param>
		/// <param name="hyphenate">Whether to hyphenate the Hex values</param>
		/// <returns>The hash as a unicode string</returns>
		public string ComputeHashAsString(string data, bool asHex = false, bool hyphenate = false)
		{
			if (!asHex)
				return Encoding.Unicode.GetString(m_provider.ComputeHash(Encoding.Unicode.GetBytes(data)));
			else
				return data.UAsByteArray().UAsHex(hyphenate);
		}

		/// <summary>
		/// Computes an MD5 hash of string data
		/// </summary>
		/// <param name="data">The byte array to compute the hash of</param>
		/// <returns>The hash as a byte array</returns>
		public byte[] ComputeHashAsByte(string data)
		{
			return m_provider.ComputeHash(Encoding.Unicode.GetBytes(data));
		}

		/// <summary>
		/// Computes an MD5 hash of a byte array
		/// </summary>
		/// <param name="data">The byte array to compute the hash of</param>
		/// <param name="asHex">Whether to express the hash as a Hex string</param>
		/// <param name="hyphenate">Whether to hyphenate the Hex values</param>
		/// <returns>The hash as a unicode string</returns>
		public string ComputeHashAsString(byte[] data, bool asHex = false, bool hyphenate = false)
		{
			if (!asHex)
				return Encoding.Unicode.GetString(m_provider.ComputeHash(data));
			else
				return data.UAsHex(hyphenate);
		}

		/// <summary>
		/// Computes an MD5 hash of a byte array
		/// </summary>
		/// <param name="data">The byte array to compute the hash of</param>
		/// <returns>The hash as a byte array</returns>
		public byte[] ComputeHashAsByte(byte[] data)
		{
			return m_provider.ComputeHash(data);
		}
	}
}